/*
 * the codes was writted by taing, but you can copy or moidfy it
 */

package com.taing.autosql.mapper;

import com.taing.autosqlutils.MyObject;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * @Author tianyi
 * @Description 通过反射实现map转实体类
 * @Date 2023 - 02 - 05
 **/
@Service
public class MapList2EntityMapperImpl<T> implements IMapList2EntityMapper {

    /**
     * @param mapList lsit<Map>入参数
     * @param clz     类
     * @return 返回实体的清单list
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    @Override
    public List modelMap2List(List mapList, Class clz) throws InstantiationException, IllegalAccessException {
        if (mapList == null || mapList.size() == 0) {
            return null;
        }
        List<T> modeList = new ArrayList<>();
        for (Object item : mapList) {
            if (item instanceof Map == false) {
                continue;
            }
            HashMap<String, Object> map = (HashMap<String, Object>) item;
            T ds = (T) clz.newInstance();
            String[] a = new String[]{"1", "3"};

            map.entrySet().stream().forEach(el -> {
                String fieldName = el.getKey();
                MyObject object = getMethodFromMapKey(fieldName);
                Field field;
                try {
                    field = clz.getDeclaredField(object.getFiledName());
                } catch (NoSuchFieldException e) {
                    throw new RuntimeException("找不到相应的方法" + object.getFiledName());
                }
                Method method;
                try {
                    method = ds.getClass().getDeclaredMethod(object.getMethodName(), field.getType());
                } catch (NoSuchMethodException e) {
                    throw new RuntimeException("找不到方法" + object.getMethodName());
                }
                try {
                    method.invoke(ds, el.getValue());
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("方法没有访问权限" + e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException("方法访问失败" + e);
                }
            });
            modeList.add(ds);
        }
        return modeList;
    }

    /***
     * 将数据加中的字段名转化成方法中的字段名，所以的规则必须是小驼峰的形势，否则会出现找不到方法的问题
     * @param fieldName
     * @return
     */
    private MyObject getMethodFromMapKey(String fieldName) {
        String[] fieldNameSpilts = fieldName.split("_");
        String methodName = "";
        for (int fieldindex = 0; fieldindex < fieldNameSpilts.length; fieldindex++) {
            methodName += fieldNameSpilts[fieldindex].substring(0, 1).toUpperCase()
                    + fieldNameSpilts[fieldindex].substring(1);
        }
        return new MyObject(methodName.substring(0, 1).toLowerCase(Locale.ENGLISH) +
                methodName.substring(1), "set" + methodName);

    }
}
